package service

import (
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"order_srv/basic/config"
	"order_srv/handler/models"
	"order_srv/handler/utils"
	"time"
)

// OrderState 订单状态枚举
type OrderState int8

const (
	// 基础状态
	StatePending    OrderState = 0 // 待确认
	StateConfirmed  OrderState = 1 // 已确认
	StateInProgress OrderState = 2 // 进行中
	StateCompleted  OrderState = 3 // 已完成
	StateCancelled  OrderState = 4 // 已取消
	StateRefunded   OrderState = 5 // 已退款

	// 扩展状态
	StateAssigned   OrderState = 6 // 已分配
	StateRejected   OrderState = 7 // 已拒绝
	StateSuspended  OrderState = 8 // 已暂停
	StateTerminated OrderState = 9 // 已终止
)

// OrderEvent 订单事件枚举
type OrderEvent string

const (
	// 基础事件
	EventAccept   OrderEvent = "accept"   // 接单
	EventReject   OrderEvent = "reject"   // 拒绝
	EventAssign   OrderEvent = "assign"   // 分配
	EventStart    OrderEvent = "start"    // 开始
	EventComplete OrderEvent = "complete" // 完成
	EventCancel   OrderEvent = "cancel"   // 取消
	EventRefund   OrderEvent = "refund"   // 退款

	// 扩展事件
	EventSuspend   OrderEvent = "suspend"   // 暂停
	EventResume    OrderEvent = "resume"    // 恢复
	EventTerminate OrderEvent = "terminate" // 终止
	EventReopen    OrderEvent = "reopen"    // 重新开启
)

// StateTransition 状态转换规则
type StateTransition struct {
	From  OrderState
	Event OrderEvent
	To    OrderState
}

// OrderStateMachine 订单状态机
type OrderStateMachine struct {
	transitions      map[OrderState]map[OrderEvent]OrderState
	validTransitions []StateTransition
}

// NewOrderStateMachine 创建订单状态机实例
func NewOrderStateMachine() *OrderStateMachine {
	sm := &OrderStateMachine{
		transitions: make(map[OrderState]map[OrderEvent]OrderState),
		validTransitions: []StateTransition{
			// 从待确认状态
			{StatePending, EventAccept, StateConfirmed},
			{StatePending, EventReject, StateRejected},
			{StatePending, EventAssign, StateAssigned},
			{StatePending, EventCancel, StateCancelled},

			// 从已确认状态
			{StateConfirmed, EventStart, StateInProgress},
			{StateConfirmed, EventCancel, StateCancelled},
			{StateConfirmed, EventSuspend, StateSuspended},

			// 从已分配状态
			{StateAssigned, EventAccept, StateConfirmed},
			{StateAssigned, EventReject, StateRejected},
			{StateAssigned, EventCancel, StateCancelled},

			// 从已拒绝状态
			{StateRejected, EventReopen, StatePending},
			{StateRejected, EventCancel, StateCancelled},

			// 从进行中状态
			{StateInProgress, EventComplete, StateCompleted},
			{StateInProgress, EventCancel, StateCancelled},
			{StateInProgress, EventSuspend, StateSuspended},
			{StateInProgress, EventTerminate, StateTerminated},

			// 从已暂停状态
			{StateSuspended, EventResume, StateInProgress},
			{StateSuspended, EventCancel, StateCancelled},
			{StateSuspended, EventTerminate, StateTerminated},

			// 从已完成状态
			{StateCompleted, EventRefund, StateRefunded},

			// 从已取消状态
			{StateCancelled, EventReopen, StatePending},

			// 从已终止状态
			{StateTerminated, EventReopen, StatePending},
		},
	}

	// 构建转换映射
	for _, transition := range sm.validTransitions {
		if sm.transitions[transition.From] == nil {
			sm.transitions[transition.From] = make(map[OrderEvent]OrderState)
		}
		sm.transitions[transition.From][transition.Event] = transition.To
	}

	return sm
}

// CanTransition 检查是否可以执行状态转换
func CanTransition(from OrderState, event OrderEvent) bool {
	sm := &OrderStateMachine{
		transitions: make(map[OrderState]map[OrderEvent]OrderState),
	}
	if transitions, exists := sm.transitions[from]; exists {
		_, canTransition := transitions[event]
		return canTransition
	}
	return false
}

// GetNextState 获取下一个状态
func GetNextState(from OrderState, event OrderEvent) (OrderState, bool) {
	sm := &OrderStateMachine{
		transitions: make(map[OrderState]map[OrderEvent]OrderState),
	}
	if transitions, exists := sm.transitions[from]; exists {
		if nextState, canTransition := transitions[event]; canTransition {
			return nextState, true
		}
	}
	return from, false
}

// GetValidEvents 获取当前状态可以执行的事件
func GetValidEvents(state OrderState) []OrderEvent {
	sm := &OrderStateMachine{
		transitions: make(map[OrderState]map[OrderEvent]OrderState),
	}
	var events []OrderEvent
	if transitions, exists := sm.transitions[state]; exists {
		for event := range transitions {
			events = append(events, event)
		}
	}
	return events
}

// GetStateName 获取状态名称
func GetStateName(state OrderState) string {
	stateNames := map[OrderState]string{
		StatePending:    "待确认",
		StateConfirmed:  "已确认",
		StateInProgress: "进行中",
		StateCompleted:  "已完成",
		StateCancelled:  "已取消",
		StateRefunded:   "已退款",
		StateAssigned:   "已分配",
		StateRejected:   "已拒绝",
		StateSuspended:  "已暂停",
		StateTerminated: "已终止",
	}
	return stateNames[state]
}

// GetEventName 获取事件名称
func GetEventName(event OrderEvent) string {
	eventNames := map[OrderEvent]string{
		EventAccept:    "接单",
		EventReject:    "拒绝",
		EventAssign:    "分配",
		EventStart:     "开始",
		EventComplete:  "完成",
		EventCancel:    "取消",
		EventRefund:    "退款",
		EventSuspend:   "暂停",
		EventResume:    "恢复",
		EventTerminate: "终止",
		EventReopen:    "重新开启",
	}
	return eventNames[event]
}

// TransitionRequest 状态转换请求
type TransitionRequest struct {
	OrderID      uint64                 `json:"order_id"`
	Event        OrderEvent             `json:"event"`
	OperatorID   string                 `json:"operator_id"`
	OperatorType string                 `json:"operator_type"`
	Reason       string                 `json:"reason"`
	ExtraData    map[string]interface{} `json:"extra_data"`
}

// TransitionResult 状态转换结果
type TransitionResult struct {
	Success   bool       `json:"success"`
	FromState OrderState `json:"from_state"`
	ToState   OrderState `json:"to_state"`
	Event     OrderEvent `json:"event"`
	Message   string     `json:"message"`
	Timestamp time.Time  `json:"timestamp"`
}

// ExecuteTransition 执行状态转换
func ExecuteTransition(ctx context.Context, req *TransitionRequest) (*TransitionResult, error) {
	//开始事务
	tx := config.DB.WithContext(ctx).Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	//1.获取当前订单状态
	var order models.Order
	err := tx.Where("id =?", req.OrderID).First(&order).Error
	if err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("订单不存在:%v", err)
	}

	currentState := OrderState(order.OrderStatus)

	//2.检查是否可以转换
	if !CanTransition(currentState, req.Event) {
		tx.Rollback()
		return &TransitionResult{
			Success:   false,
			FromState: currentState,
			ToState:   currentState,
			Event:     req.Event,
			Message:   fmt.Sprintf("无法从状态'%s' 执行事件 '%s'", GetStateName(currentState), GetEventName(req.Event)),
			Timestamp: time.Now(),
		}, nil
	}
	//3.获取下一个状态
	nextState, _ := GetNextState(currentState, req.Event)

	//4.执行状态转换
	updateData := map[string]interface{}{
		"order+status": int8(nextState),
		"updated_at":   time.Now(),
	}
	//根据时间类型设置特殊字段
	switch req.Event {
	case EventCancel:
		updateData["cancel_reason"] = req.Reason
		updateData["cancel_time"] = time.Now()
	case EventComplete:
		updateData["actual_end_data"] = time.Now()
	case EventStart:
		updateData["actual_start_date"] = time.Now()
	}

	//更新订单状态
	if err := tx.Model(&order).Updates(updateData).Error; err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("更新订单状态失败：%w", err)
	}
	//5.记录状态变更日志
	statusLog := models.OrderStatusLog{
		OrderID:      req.OrderID,
		OperatorID:   req.OperatorID,
		OperatorType: getOperatorTypeInt(req.OperatorType),
		Reason:       req.Reason,
		CreatedAt:    time.Now(),
		NewStatus:    int(nextState),
		OldStatus:    int(currentState),
		OrderNo:      order.OrderNo,
	}

	if err := tx.Create(&statusLog).Error; err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("记录状态变更日志失败: %w", err)
	}

	// 6. 记录接单操作（如果是接单相关事件）
	if req.Event == EventAccept || req.Event == EventReject || req.Event == EventAssign {
		acceptance := models.OrderAcceptance{
			OrderID:      req.OrderID,
			OrderNo:      order.OrderNo,
			OperatorID:   req.OperatorID,
			OperatorType: req.OperatorType,
			Action:       string(req.Event),
			Reason:       req.Reason,
			ProcessedAt:  time.Now(),
			ResponseTime: time.Since(order.CreatedAt).Milliseconds(),
		}
		if err := tx.Create(&acceptance).Error; err != nil {
			tx.Rollback()
			return nil, fmt.Errorf("记录接单操作失败: %w", err)
		}
	}

	// 7. 执行后置处理
	if err := executePostTransition(ctx, tx, &order, currentState, nextState, req); err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("执行后置处理失败: %w", err)
	}

	tx.Commit()

	return &TransitionResult{
		Success:   true,
		FromState: currentState,
		ToState:   nextState,
		Event:     req.Event,
		Message:   fmt.Sprintf("状态从 '%s' 成功转换为 '%s'", GetStateName(currentState), GetStateName(nextState)),
		Timestamp: time.Now(),
	}, nil
}

// executePostTransition 执行后置处理
func executePostTransition(ctx context.Context, tx *gorm.DB, order *models.Order, fromState, toState OrderState, req *TransitionRequest) error {
	switch toState {
	case StateConfirmed:
		// 接单后更新操作员统计
		if req.OperatorID != "" {
			return updateOperatorStats(tx, req.OperatorID, true)
		}
	case StateRejected:
		// 拒绝后可能需要通知其他操作员
		return notifyOtherOperators(ctx, order.ID, "订单已被拒绝")
	case StateCompleted:
		// 完成后更新相关统计
		return updateCompletionStats(ctx, tx, order)
	case StateCancelled:
		// 取消后可能需要退款处理
		return handleCancellation(ctx, tx, order, req.Reason)
	}
	return nil
}

// updateOperatorStats 更新操作员统计
func updateOperatorStats(tx *gorm.DB, operatorID string, isAccept bool) error {
	var operator models.Operator
	err := tx.Where("operator_id = ?", operatorID).First(&operator).Error
	if err != nil {
		return fmt.Errorf("操作员不存在: %v", err)
	}

	if isAccept {
		operator.CurrentOrderCount++
	} else {
		if operator.CurrentOrderCount > 0 {
			operator.CurrentOrderCount--
		}
	}

	operator.LastActiveTime = &[]time.Time{time.Now()}[0]
	return tx.Save(&operator).Error
}

// notifyOtherOperators 通知其他操作员
func notifyOtherOperators(ctx context.Context, orderID uint64, message string) error {
	// 这里可以实现通知逻辑，比如发送WebSocket消息
	err := utils.LogOrderOperation(ctx, "通知其他操作员", message, "", "", "")
	if err != nil {
		return errors.New("记录通知错误")
	}
	// 暂时返回nil，实际实现中可以集成通知系统
	return nil
}

// updateCompletionStats 更新完成统计
func updateCompletionStats(ctx context.Context, tx *gorm.DB, order *models.Order) error {
	// 更新相关统计信息
	var operator models.Operator
	err := tx.Where("operator_id = ?", order.LandlordID).First(&operator).Error
	if err != nil {
		return fmt.Errorf("房东不存在: %v", err)
	}
	err = utils.LogOrderOperation(ctx, "完成订单", order.OrderNo, order.LandlordID, order.TenantID, order.AgentID)
	if err != nil {
		return errors.New("记录完成订单错误")
	}
	return nil
}

// handleCancellation 处理取消逻辑
func handleCancellation(ctx context.Context, tx *gorm.DB, order *models.Order, reason string) error {
	// 处理取消相关的业务逻辑
	var operator models.Operator
	err := tx.Where("operator_id = ?", order.LandlordID).First(&operator).Error
	if err != nil {
		return fmt.Errorf("房东不存在: %v", err)
	}
	err = utils.LogOrderError(ctx, "取消订单", order.OrderNo, order.LandlordID, order.TenantID, order.AgentID, reason)
	if err != nil {
		return errors.New("记录取消订单错误")
	}
	return nil
}

// getOperatorTypeInt 获取操作员类型整数
func getOperatorTypeInt(operatorType string) int8 {
	switch operatorType {
	case "agent":
		return 1
	case "landlord":
		return 2
	case "admin":
		return 3
	default:
		return 1
	}
}

type Transition struct {
	OrderStateMachine *OrderStateMachine
}

// GetStateMachineDiagram 获取状态机流程图数据
func GetStateMachineDiagram() map[string]interface{} {
	var nodes []map[string]interface{}
	var edges []map[string]interface{}

	// 添加状态节点
	stateList := []OrderState{
		StatePending, StateConfirmed, StateInProgress, StateCompleted,
		StateCancelled, StateRefunded, StateAssigned, StateRejected,
		StateSuspended, StateTerminated,
	}

	for _, state := range stateList {
		node := map[string]interface{}{
			"id":    int(state),
			"label": GetStateName(state),
			"type":  "state",
		}

		// 设置节点颜色
		switch state {
		case StatePending:
			node["color"] = "#FFA500" // 橙色
		case StateConfirmed:
			node["color"] = "#32CD32" // 绿色
		case StateInProgress:
			node["color"] = "#4169E1" // 蓝色
		case StateCompleted:
			node["color"] = "#228B22" // 深绿色
		case StateCancelled:
			node["color"] = "#DC143C" // 红色
		case StateRefunded:
			node["color"] = "#8B008B" // 紫色
		default:
			node["color"] = "#808080" // 灰色
		}

		nodes = append(nodes, node)
	}
	var validTransitions []StateTransition

	for _, transition := range validTransitions {
		edge := map[string]interface{}{
			"from":  int(transition.From),
			"to":    int(transition.To),
			"label": GetEventName(transition.Event),
		}
		edges = append(edges, edge)
	}

	return map[string]interface{}{
		"nodes": nodes,
		"edges": edges,
		"title": "订单状态机流程图",
	}
}
